{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[-0.017612, 14.053064],\n",
       "        [-0.752157,  6.53862 ],\n",
       "        [-1.322371,  7.152853],\n",
       "        [ 0.423363, 11.054677],\n",
       "        [ 0.667394, 12.741452]]),\n",
       " array([[-1.395634,  4.662541],\n",
       "        [ 0.406704,  7.067335],\n",
       "        [-2.46015 ,  6.866805],\n",
       "        [ 0.850433,  6.920334],\n",
       "        [ 1.176813,  3.16702 ]]))"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "#加载数据\n",
    "def load_data():\n",
    "    with open('简单分类数据.txt') as fr:\n",
    "        lines = fr.readlines()\n",
    "\n",
    "    x = np.empty((len(lines), 2), dtype=float)\n",
    "    y = np.empty(len(lines), dtype=int)\n",
    "\n",
    "    for i in range(len(lines)):\n",
    "        line = lines[i].strip().split('\\t')\n",
    "        x[i] = line[:2]\n",
    "        y[i] = line[2]\n",
    "\n",
    "    #以y区分两类x\n",
    "    x0 = x[y == -1]\n",
    "    x1 = x[y == 1]\n",
    "\n",
    "    return x0, x1\n",
    "\n",
    "\n",
    "x0, x1 = load_data()\n",
    "x0[:5], x1[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 0.08204613, 10.65488423]), array([-0.01613109,  2.95908379]))"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#求向量均值\n",
    "mu0 = x0.mean(axis=0)\n",
    "mu1 = x1.mean(axis=0)\n",
    "mu0, mu1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[0.9579532 , 0.54249108],\n",
       "        [0.54249108, 3.70851954]]),\n",
       " array([[1.75563826, 2.04944407],\n",
       "        [2.04944407, 9.42458334]]))"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#求协方差矩阵\n",
    "sigma0 = np.cov(x0, rowvar=False)\n",
    "sigma1 = np.cov(x1, rowvar=False)\n",
    "sigma0, sigma1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[ 2.71359145,  2.59193514],\n",
       "        [ 2.59193514, 13.13310288]]),\n",
       " array([[9.63876692e-03, 7.55552308e-01],\n",
       "        [7.55552308e-01, 5.92253444e+01]]))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#按照书上的思路,定义sw和sb\n",
    "sw = sigma0 + sigma1\n",
    "sb = np.outer(mu0 - mu1, mu0 - mu1)\n",
    "\n",
    "sw, sb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[ 0.45412231, -0.08962509],\n",
       "        [-0.08962509,  0.09383178]]),\n",
       " array([[ 0.45412231, -0.08962509],\n",
       "        [-0.08962509,  0.09383178]]))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#求sw的逆矩阵\n",
    "#奇异值分解\n",
    "u, sigma, v = np.linalg.svd(sw, full_matrices=False)\n",
    "\n",
    "#求逆矩阵\n",
    "sw_I = np.matmul(v.T / sigma, u.T)\n",
    "\n",
    "#两者等价，但是使用奇异值分解的方式可以保证数值的稳定性\n",
    "sw_I, np.linalg.inv(sw)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.64515237,  0.71331152])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#约束:w * sw * w.T = 1\n",
    "#求最大:w * sb * w.T\n",
    "#w = sw.I * (mu0 - mu1)\n",
    "w = sw_I.dot(mu0 - mu1)\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([10.03557485,  5.14932884,  5.95534323,  7.61229479,  8.65805365]),\n",
       " array([4.22624079, 4.77882541, 6.48534272, 4.38769508, 1.49984814]))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#投影\n",
    "#(N,2) * (2,1) = (N,1)\n",
    "p0 = x0.dot(w)\n",
    "p1 = x1.dot(w)\n",
    "\n",
    "p0[:5], p1[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "def draw():\n",
    "    plt.scatter(x0[:, 0], x0[:, 1], c='red')\n",
    "    plt.scatter(x1[:, 0], x1[:, 1], c='blue')\n",
    "\n",
    "    plt.show()\n",
    "\n",
    "    plt.scatter(p0, np.zeros(len(p0)), c='red')\n",
    "    plt.scatter(p1, np.zeros(len(p1)), c='blue')\n",
    "\n",
    "    plt.scatter(p0.mean(), 1, c='red')\n",
    "    plt.scatter(p1.mean(), 1, c='blue')\n",
    "\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "draw()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#预测函数\n",
    "def predict(p):\n",
    "    d0 = np.power(p - p0.mean(), 2)\n",
    "    d1 = np.power(p - p1.mean(), 2)\n",
    "    pred = 1 if d0 > d1 else -1\n",
    "    return pred\n",
    "\n",
    "\n",
    "predict(p0[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.97"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#测试\n",
    "correct = 0\n",
    "for i in p0:\n",
    "    if predict(i) == -1:\n",
    "        correct += 1\n",
    "\n",
    "for i in p1:\n",
    "    if predict(i) == 1:\n",
    "        correct += 1\n",
    "\n",
    "correct / (len(p0) + len(p1))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
